package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dto.*;
import com.example.entity.*;
import com.example.mapper.*;
import com.example.service.CartInfoService;
import com.example.util.BeanCopyPropertiesUtils;
import com.example.util.RedisUtil;
import com.example.vo.IdHolder;
import com.example.vo.buyer.CartGroupedByStoreVo;
import com.example.vo.buyer.CartItemVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.example.constant.RedisConstance.USER_ORDER_TOKEN_PREFIX;

/**
* @author 朽
*/
@Service
@Slf4j
public class CartInfoServiceImpl extends ServiceImpl<CartInfoMapper, CartInfo>
    implements CartInfoService {

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private SkuAttrValueMapper skuAttrValueMapper;

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private AttrMapper attrMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private RedisUtil redisUtil;


    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<CartGroupedByStoreVo> getCartItemsByUserId(Long userId) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart != null) {
            return (List<CartGroupedByStoreVo>) cachedCart;
        } else {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = getCartItems(userId);
            redisUtil.set(redisKey, cartGroupedByStoreVos);
            return cartGroupedByStoreVos;
        }
    }

    @Override
    public boolean addCart(Long userId, CartItemDto cartItemDto){
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        List<CartGroupedByStoreVo> cartGroupedByStoreVos;
        if (cachedCart != null) {
            cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
        } else {
            cartGroupedByStoreVos = getCartItems(userId);
            redisUtil.set(redisKey, cartGroupedByStoreVos);
        }
        boolean exists = false;
        for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
            for (CartItemVo itemVo : storeVo.getItems()) {
                if (itemVo.getSkuId().equals(cartItemDto.getSkuId())) {
                    // 如果存在，增加商品数量
                    int newQuantity = itemVo.getCount() + cartItemDto.getQuantity();
                    itemVo.setCount(newQuantity);
                    exists = true;
                    break;
                }
            }
            if (exists) {
                redisUtil.set(redisKey, cartGroupedByStoreVos);
                break;
            }
            else {
                CartInfo newCartInfo = converByCartItemDto(userId,cartItemDto);
                cartGroupedByStoreVos = addItemToCartGroupedByStore(cartGroupedByStoreVos, newCartInfo);
                // 更新Redis中的数据
                redisUtil.set(redisKey, cartGroupedByStoreVos);
                exists = true;
                break;
            }
        }

        if (!exists) {
            CartInfo newCartInfo = converByCartItemDto(userId,cartItemDto);
            List<CartInfo> newCartInfos = new ArrayList<>();
            newCartInfos.add(newCartInfo);
            List<CartGroupedByStoreVo> newCartGroupedByStoreVos = processCartItems(newCartInfos);
            cartGroupedByStoreVos.addAll(newCartGroupedByStoreVos);
            redisUtil.set(redisKey, cartGroupedByStoreVos);
        }
        return true;
    }

    public CartInfo converByCartItemDto(Long userId, CartItemDto cartItemDto){
        CartInfo newCartInfo = new CartInfo();
        newCartInfo.setUserId(userId);
        newCartInfo.setSkuId(cartItemDto.getSkuId());
        newCartInfo.setCount(cartItemDto.getQuantity());
        newCartInfo.setSaleAttrs(cartItemDto.getSaleAttrs());
        newCartInfo.setCheck(0);
        return newCartInfo;
    }

    public List<CartGroupedByStoreVo> getCartItems(Long userId) {
        List<CartInfo> cartInfos = baseMapper.getAllByUserId(userId);
        return processCartItems(cartInfos);
    }

    public List<CartGroupedByStoreVo> addItemToCartGroupedByStore(List<CartGroupedByStoreVo> cartGroupedByStoreVos, CartInfo newCartInfo) {
        CartItemVo vo = convert(newCartInfo);
        Long storeId = skuMapper.getSkuBySkuId(Math.toIntExact(vo.getSkuId())).getStoreId();
        for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
            if (storeVo.getStoreId().equals(storeId)) {
                storeVo.getItems().add(vo);
                return cartGroupedByStoreVos;
            }
        }
        Store store = storeMapper.selectStoreById(storeId);
        String storeName = store.getName();
        CartGroupedByStoreVo newStoreVo = new CartGroupedByStoreVo();
        newStoreVo.setStoreId(storeId);
        newStoreVo.setStoreName(storeName);
        newStoreVo.setItems(new ArrayList<>());
        newStoreVo.getItems().add(vo);
        cartGroupedByStoreVos.add(newStoreVo);
        return cartGroupedByStoreVos;
    }

    public CartItemVo convert(CartInfo cartInfo) {
        ModelMapper modelMapper = new ModelMapper();

        if (cartInfo.getId() == null) {
            long timestamp = System.currentTimeMillis();
            long random = ThreadLocalRandom.current().nextLong(0, 100000);
            long uniqueId = timestamp + random;
            cartInfo.setId(uniqueId);
        }
        CartItemVo cartItemVo = modelMapper.map(cartInfo, CartItemVo.class);

        // 查询 SKU 信息
        Sku sku = skuMapper.selectById(cartInfo.getSkuId());
        cartItemVo.setSkuName(sku.getName());
        cartItemVo.setSkuImage(sku.getDefaultImage());
        cartItemVo.setSkuPrice(sku.getPrice());
        cartItemVo.setStock(sku.getStock());
        cartItemVo.setQuantity(sku.getStock() > sku.getSell() ? sku.getStock() - sku.getSell() : 0);

        // 查询 SPU 信息
        Spu spu = spuMapper.selectById(sku.getSpuId());
        cartItemVo.setSpuName(spu.getName());
        cartItemVo.setSpuId(spu.getId());
        cartItemVo.setCategoryId(spu.getCategoryId());

        // 查询属性信息
        Map<String, List<String>> attrValuesMap = new HashMap<>();
        List<SkuAttrValue> skuAttrValues = skuAttrValueMapper.selectList(new QueryWrapper<SkuAttrValue>().eq("sku_id", cartInfo.getSkuId()));
        for (SkuAttrValue skuAttrValue : skuAttrValues) {
            Attr attr = attrMapper.selectById(skuAttrValue.getAttrId());
            if (attr != null) {
                if (attr.getValueSelect() != null && !attr.getValueSelect().isEmpty()) {
                    // 去掉逗号并存储 valueSelect 中的每个值
                    List<String> attrValues = Arrays.asList(attr.getValueSelect().split("\\s*,\\s*"));
                    attrValuesMap.put(attr.getName(), attrValues);
                }
            }
        }
        cartItemVo.setAttrValuesMap(attrValuesMap);
        return cartItemVo;
    }

    public List<CartGroupedByStoreVo> processCartItems(List<CartInfo> cartInfos) {
        Map<Long, CartGroupedByStoreVo> storeMap = new HashMap<>();

        for (CartInfo cartInfo : cartInfos) {
            CartItemVo cartItemVo = convert(cartInfo);
            Long storeId = skuMapper.getSkuBySkuId(Math.toIntExact(cartItemVo.getSkuId())).getStoreId();
            // 查询店铺名称
            Store store = storeMapper.selectStoreById(storeId);
            String storeName = store.getName();

            CartGroupedByStoreVo storeVo = storeMap.get(storeId);

            if (storeVo == null) {
                storeVo = new CartGroupedByStoreVo();
                storeVo.setStoreId(storeId);
                storeVo.setStoreName(storeName);
                storeVo.setItems(new ArrayList<>());
                storeMap.put(storeId, storeVo);
            }
            storeVo.getItems().add(cartItemVo);
        }
        return new ArrayList<>(storeMap.values());
    }

    @Override
    public boolean updateByItemCheck(Long userId, Long id, Integer check){
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart instanceof List) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            boolean isUpdated = false;

            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                for (CartItemVo itemVo : storeVo.getItems()) {
                    if (itemVo.getId().equals(id)) {
                        itemVo.setCheck(check);
                        isUpdated = true;
                        break;
                    }
                }
                if (isUpdated) {
                    redisUtil.set(redisKey, cartGroupedByStoreVos);
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean updateByStoreCheck(Long userId, Long storeId, Integer check) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart instanceof List) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            boolean isUpdated = false;

            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                if (storeVo.getStoreId().equals(storeId)) {
                    for (CartItemVo itemVo : storeVo.getItems()) {
                        itemVo.setCheck(check);
                        isUpdated = true;
                    }
                    redisUtil.set(redisKey, cartGroupedByStoreVos);
                    break;
                }
            }
            return isUpdated;
        }
        return false;
    }

    @Override
    public boolean updateAllItemCheck(Long userId, Integer check) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (Objects.equals(cachedCart, null) || ((List<?>) cachedCart).isEmpty()) {
            return true;
        }
        if (cachedCart instanceof List) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            boolean isUpdated = false;

            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                for (CartItemVo itemVo : storeVo.getItems()) {
                    itemVo.setCheck(check);
                    isUpdated = true;
                }
            }
            if (isUpdated) {
                redisUtil.set(redisKey, cartGroupedByStoreVos);
            }
            return isUpdated;
        }
        return false;
    }

    @Override
    public boolean updateCount(Long userId, Long id, Integer newQuantity){
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart instanceof List) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            boolean isUpdated = false;

            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                for (CartItemVo itemVo : storeVo.getItems()) {
                    if (itemVo.getId().equals(id)) {
                        itemVo.setCount(newQuantity);
                        isUpdated = true;
                        break;
                    }
                }
                if (isUpdated) {
                    redisUtil.set(redisKey, cartGroupedByStoreVos);
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean deleteAllCart(Long userId) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart instanceof List) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            Iterator<CartGroupedByStoreVo> iterator = cartGroupedByStoreVos.iterator();
            while (iterator.hasNext()) {
                CartGroupedByStoreVo storeVo = iterator.next();
                storeVo.getItems().clear();
                if (storeVo.getItems().isEmpty()) {
                    iterator.remove();
                }
            }

            if (cartGroupedByStoreVos.isEmpty()) {
                try {
                    redisUtil.set(redisKey, cartGroupedByStoreVos);
                    return true;
                } catch (Exception e) {
                    return false;
                }
            }
        }
        return false;
    }

    @Override
    public boolean deleteItemBySkuId(Long userId, Long skuId) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart != null) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            boolean isDeleted = false;
            for (Iterator<CartGroupedByStoreVo> storeVoIterator = cartGroupedByStoreVos.iterator(); storeVoIterator.hasNext();) {
                CartGroupedByStoreVo storeVo = storeVoIterator.next();
                Iterator<CartItemVo> itemVoIterator = storeVo.getItems().iterator();
                while (itemVoIterator.hasNext()) {
                    CartItemVo itemVo = itemVoIterator.next();
                    if (itemVo.getSkuId().equals(skuId)) {
                        itemVoIterator.remove();
                        isDeleted = true;
                        break;
                    }
                }
                // 如果该店铺下没有商品了，则删除该店铺的购物车信息
                if (storeVo.getItems().isEmpty()) {
                    storeVoIterator.remove();
                }
            }
            // 商品被删除时，更新Redis
            if (isDeleted) {
                redisUtil.set(redisKey, cartGroupedByStoreVos);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean updateByItem(Long userId, UpdatedItemDto updatedItemDto) {
        ObjectMapper objectMapper = new ObjectMapper();
        Integer count = updatedItemDto.getCount();
        try {
            Long spuId = updatedItemDto.getSpuId();
            List<Long> lockedSkuIds = skuMapper.findSkuIdBySpuId(spuId);
            if (lockedSkuIds == null || lockedSkuIds.isEmpty()) {
                return false;
            }

            Map<String, String> incomingSaleAttrs = objectMapper.readValue(updatedItemDto.getSaleAttrs(), Map.class);
            String saleAttrsJson = objectMapper.writeValueAsString(incomingSaleAttrs);

            //获取对应SkuId
            Long matchedSkuId = null;
            for (Long lockedSkuId : lockedSkuIds) {
                List<Map<String, String>> dbSaleAttrsList = skuAttrValueMapper.findSaleAttrsBySkuId(lockedSkuId);
                Map<String, String> dbSaleAttrs = new HashMap<>();
                for (Map<String, String> entry : dbSaleAttrsList) {
                    dbSaleAttrs.put(entry.get("key"), entry.get("value"));
                }
                String dbSaleAttrsJson = objectMapper.writeValueAsString(dbSaleAttrs);

                if (dbSaleAttrsJson.equals(saleAttrsJson)) {
                    matchedSkuId = lockedSkuId;
                    break;
                }
            }

            if (matchedSkuId == null) {
                return false;
            }

            // 从 Redis 中获取购物车数据
            String redisKey = "user:" + userId + ":cart";
            Object cachedCart = redisUtil.get(redisKey);
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;

            final Long matchSkuId = matchedSkuId;
            if (cartGroupedByStoreVos != null) {
                // 检查购物车中是否包含特定商品ID
                boolean containsSkuId = cartGroupedByStoreVos.stream()
                        .flatMap(storeVo -> storeVo.getItems().stream())
                        .anyMatch(itemVo -> itemVo.getSkuId().equals(matchSkuId));

                if (containsSkuId) {
                    for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                        Iterator<CartItemVo> itemVoIterator = storeVo.getItems().iterator();
                        while (itemVoIterator.hasNext()) {
                            CartItemVo itemVo = itemVoIterator.next();
                            if (itemVo.getSkuId().equals(matchedSkuId)) {
                                itemVo.setCount(itemVo.getCount() + count);
                            }
                            if (itemVo.getSkuId().equals(updatedItemDto.getSkuId())) {
                                itemVoIterator.remove();
                            }
                        }
                    }
                } else {
                    Sku sku = skuMapper.getSkuBySkuId(Math.toIntExact(matchedSkuId));
                    for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                        for (CartItemVo itemVo : storeVo.getItems()) {
                            if (itemVo.getSkuId().equals(updatedItemDto.getSkuId())) {
                                itemVo.setSkuId(matchedSkuId);
                                itemVo.setSkuName(sku.getName());
                                itemVo.setSkuImage(sku.getDefaultImage());
                                itemVo.setSkuPrice(sku.getPrice());
                                itemVo.setStock(sku.getStock());
                                itemVo.setSaleAttrs(saleAttrsJson);
                                itemVo.setQuantity(sku.getStock() > sku.getSell() ? sku.getStock() - sku.getSell() : 0);
                                break;
                            }
                        }
                    }
                }
                redisUtil.set(redisKey, cartGroupedByStoreVos);
                return true;
            }
        }
        catch(IOException e){
            log.error("Error: ", e);
        }
        return false;
    }

    @Override
    public void asyncSyncCartWithDatabaseOnLogout(Long userId) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart instanceof List && !((List<?>) cachedCart).isEmpty()) {
            List<CartGroupedByStoreVo> cartGroupedByStoreVos = (List<CartGroupedByStoreVo>) cachedCart;
            // 获取数据库中的购物车数据
            List<CartInfo> dbCartInfos = baseMapper.getAllByUserId(userId);

            // 创建一个用于比较的Map
            Map<Long, CartInfo> dbCartMap = dbCartInfos.stream()
                    .collect(Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));

            // 遍历Redis中的购物车数据
            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                for (CartItemVo itemVo : storeVo.getItems()) {
                    Long skuId = itemVo.getSkuId();
                    CartInfo dbCartInfo = dbCartMap.get(skuId);

                    // 如果数据库中有对应的购物车项，更新数据
                    if (dbCartInfo != null) {
                        if (!dbCartInfo.getCount().equals(itemVo.getCount()) ||
                                !dbCartInfo.getCheck().equals(itemVo.getCheck())) {
                            baseMapper.updateCartInfo(dbCartInfo.getId(),itemVo.getCount(),itemVo.getCheck());
                        }
                    } else {
                        // 添加
                        CartInfo newCartInfo = new CartInfo();
                        newCartInfo.setUserId(userId);
                        newCartInfo.setSkuId(skuId);
                        newCartInfo.setCheck(itemVo.getCheck());
                        newCartInfo.setCount(itemVo.getCount());
                        newCartInfo.setSaleAttrs(itemVo.getSaleAttrs());
                        baseMapper.insertCartInfo(newCartInfo);
                    }
                }
            }

            // 检查数据库中是否有已删除的购物车项
            // 构建一个包含所有Redis中skuId的集合
            Set<Long> redisSkuIds = new HashSet<>();
            for (CartGroupedByStoreVo storeVo : cartGroupedByStoreVos) {
                for (CartItemVo itemVo : storeVo.getItems()) {
                    redisSkuIds.add(itemVo.getSkuId());
                }
            }

            // 如果Redis中不存在，删除购物车项
            for (CartInfo dbCartInfo : dbCartInfos) {
                if (!redisSkuIds.contains(dbCartInfo.getSkuId())) {
                    baseMapper.deleteItemBySkuId(userId, dbCartInfo.getSkuId());
                }
            }
        } else {
            // 如果Redis中没有数据，删除数据库中的所有购物车项
            baseMapper.deleteCart(userId);
        }
        redisUtil.delete(redisKey);
    }

    @Override
    public TradeDTO settleOrder() {
        Long userId = IdHolder.getUserId();
        List<CartGroupedByStoreVo> cartGroupedByStoreVos = getCartFromRedis(userId);
        List<CartGroupedByStoreVo> selectedItemsByStore = getSelectedItemsByStore(cartGroupedByStoreVos);

        List<OrderDTO> orders = applyDiscountsAndCreateOrders(selectedItemsByStore);

        // 创建 TradeDTO 实例
        TradeDTO trade = new TradeDTO();
        trade.setOrders(orders);
        String token = UUID.randomUUID().toString().replace("-", "");
        trade.setOrderToken(token);
        // 防重令牌
        stringRedisTemplate.opsForValue().set(USER_ORDER_TOKEN_PREFIX + ":" + userId, token, 30, TimeUnit.MINUTES);// 计算总价格、优惠金额等
        BigDecimal totalGoodsPrice = BigDecimal.ZERO;
        BigDecimal totalDiscountPrice = BigDecimal.ZERO;
        BigDecimal totalFlowPrice = BigDecimal.ZERO;
        BigDecimal totalFreightPrice = BigDecimal.ZERO;

        for (OrderDTO order : orders) {
            totalGoodsPrice = totalGoodsPrice.add(order.getTotalAmount());
            totalDiscountPrice = totalDiscountPrice.add(order.getCouponAmount());
            totalFreightPrice = totalFreightPrice.add(order.getFreightAmount());

        }
        totalFlowPrice = totalGoodsPrice.subtract(totalDiscountPrice).add(totalFreightPrice);

        // 设置 TradeDTO 的价格信息
        trade.setGoodsPrice(totalGoodsPrice);
        trade.setDiscountPrice(totalDiscountPrice);
        trade.setFlowPrice(totalFlowPrice);
        trade.setFreightPrice(totalFreightPrice);
        log.info("00:{}",trade);
        return trade;
    }

    @Override
    public List<CartGroupedByStoreVo> getCartFromRedis(Long userId) {
        String redisKey = "user:" + userId + ":cart";
        Object cachedCart = redisUtil.get(redisKey);
        if (cachedCart != null) {
            return (List<CartGroupedByStoreVo>) cachedCart;
        }
        return new ArrayList<>();
    }

    @Override
    public List<CartGroupedByStoreVo> getSelectedItemsByStore(List<CartGroupedByStoreVo> cartGroupedByStoreVos) {
        return cartGroupedByStoreVos.stream()
                .map(storeVo -> {
                    List<CartItemVo> selectedItems = storeVo.getItems().stream()
                            .filter(item -> item.getCheck() != null && item.getCheck() == 1)
                            .collect(Collectors.toList());
                    if (!selectedItems.isEmpty()) {
                        CartGroupedByStoreVo selectedStoreVo = new CartGroupedByStoreVo();
                        selectedStoreVo.setStoreId(storeVo.getStoreId());
                        selectedStoreVo.setStoreName(storeVo.getStoreName());
                        selectedStoreVo.setItems(selectedItems);
                        return selectedStoreVo;
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    private List<OrderDTO> applyDiscountsAndCreateOrders(List<CartGroupedByStoreVo> selectedItemsByStore) {
        List<OrderDTO> orders = new ArrayList<>();
        for (CartGroupedByStoreVo storeVo : selectedItemsByStore) {
            OrderDTO order = BeanCopyPropertiesUtils.copyBean(storeVo, OrderDTO.class);
            List<CartItemVo> selectedItems = storeVo.getItems();

            BigDecimal totalDiscountAmount = BigDecimal.ZERO;
            BigDecimal totalAmount = BigDecimal.ZERO;
            List<String> usedCouponIds = new ArrayList<>();
            // 遍历商品项，累加总金额和总优惠金额
            for (CartItemVo item : selectedItems) {
                totalAmount = totalAmount.add(item.getSkuPrice().multiply(new BigDecimal(item.getCount())));

                // 检查item.getCouponAmount()是否为null
                BigDecimal couponAmount = item.getCouponAmount();
                if (couponAmount == null) {
                    couponAmount = BigDecimal.ZERO;
                }
                totalDiscountAmount = totalDiscountAmount.add(couponAmount);

                if (item.getCouponIds() != null && !item.getCouponIds().isEmpty()) {
                    String[] ids = item.getCouponIds().split(",");
                    Collections.addAll(usedCouponIds, ids);
                }
            }

            order.setItems(convertToOrderItems(selectedItems));
            order.setTotalAmount(totalAmount);
            order.setCouponAmount(totalDiscountAmount);
            order.setPayAmount(totalAmount.subtract(totalDiscountAmount));
            order.setNote("订单备注");
            order.setPromotionAmount(BigDecimal.ZERO);
            order.setFreightAmount(BigDecimal.ZERO);
            order.setDiscountAmount(totalDiscountAmount);
            if (!usedCouponIds.isEmpty()) {
                String couponIdsStr = usedCouponIds.stream()
                        .distinct()
                        .collect(Collectors.joining(","));
                order.setCouponIds(couponIdsStr);
            }

            orders.add(order);
        }
        return orders;
    }


    private List<OrderItemDTO> convertToOrderItems(List<CartItemVo> cartItems) {
        List<OrderItemDTO> orderItems = new ArrayList<>();
        for (CartItemVo cartItem : cartItems) {

        // 使用 BeanCopyPropertiesUtils 复制属性
            OrderItemDTO orderItem = BeanCopyPropertiesUtils.copyBean(cartItem, OrderItemDTO.class);
        // 手动设置 skuPic 和 skuQuantity 的值
            orderItem.setSkuPic(cartItem.getSkuImage());
            orderItem.setSkuQuantity(cartItem.getCount());
            orderItem.setSkuAttrsVals(cartItem.getSaleAttrs());
            orderItems.add(orderItem);
        }
        return orderItems;
    }

    @Override
    public BigDecimal calculateTotalPriceFromRedis(Long userId) {
        List<CartGroupedByStoreVo> cartGroupedByStoreVos = getCartFromRedis(userId);
        List<CartGroupedByStoreVo> selectedItemsByStore = getSelectedItemsByStore(cartGroupedByStoreVos);

        BigDecimal totalAmount = BigDecimal.ZERO;
        for (CartGroupedByStoreVo storeVo : selectedItemsByStore) {
            for (CartItemVo item : storeVo.getItems()) {
                if (item.getRealAmount() != null) {
                    totalAmount = totalAmount.add(item.getRealAmount());
                } else {
                    totalAmount = totalAmount.add(item.getSkuPrice().multiply(BigDecimal.valueOf(item.getCount())));
                }


            }
        }

        return totalAmount;
    }

}








